﻿using Abp.Application.Features;
using Abp.Auditing;
using Abp.Authorization;
using Abp.Authorization.Roles;
using Abp.Authorization.Users;
using Abp.IdentityServer4vNext;
using Abp.Localization;
using Abp.MultiTenancy;
using Abp.Notifications;
using Abp.Organizations;
using Microsoft.EntityFrameworkCore;
using Mt.Organizations;
using Mt.Site.Core.AccessStatistics.Entities;
using Mt.Site.Core.Authorization.Delegation;
using Mt.Site.Core.Authorization.Users.Entities;
using Mt.Site.Core.BackGroundJobs.Entities;
using Mt.Site.Core.Base.Authorization.Roles;
using Mt.Site.Core.Base.Authorization.Users;
using Mt.Site.Core.Base.Domain.Entities.ShortId;
using Mt.Site.Core.Base.EntityFrameworkCore;
using Mt.Site.Core.Base.Localization;
using Mt.Site.Core.Cache.Entities;
using Mt.Site.Core.Chat;
using Mt.Site.Core.ContentManagement.Entities;
using Mt.Site.Core.CustomConfigurations;
using Mt.Site.Core.DataLogs;
using Mt.Site.Core.DiyContent.Form.Entities;
using Mt.Site.Core.Friendships;
using Mt.Site.Core.Members;
using Mt.Site.Core.Messages_;
using Mt.Site.Core.Navigations.Entities;
using Mt.Site.Core.Notifications;
using Mt.Site.Core.Organizations.Posts;
using Mt.Site.Core.SEO;
using Mt.Site.Core.StaticPages;
using Mt.Site.Core.Storage;
using Mt.Site.Core.Storage.File_;
using Mt.Site.Core.Taxonomys.Entities;
using Mt.Site.Core.VerifyCodes;
using Mt.Site.Core.VersionBackup.Entities;
using Mt.Site.Core.WorkFlows.Design.Entities;
using Mt.Site.Core.WorkFlows.Process.Entities;

namespace Mt.Site.EntityFrameworkCore
{
    /* Constructors of this DbContext is important and each one has it's own use case.
     * - Default constructor is used by EF tooling on design time.
     * - constructor(nameOrConnectionString) is used by ABP on runtime.
     * - constructor(existingConnection) is used by unit tests.
     * - constructor(existingConnection,contextOwnsConnection) can be used by ABP if DbContextEfTransactionStrategy is used.
     */
    public class MtSiteDbContext : MtSiteBaseDbContext<MtSiteDbContext>, IAbpPersistedGrantDbContext
    {
        public virtual DbSet<Messages> Messages { get; set; }


        public virtual DbSet<Member> Members { get; set; }
        // 会员信息
        public virtual DbSet<MemberInfo> MemberInfos { get; set; }
        // 验证码
        public virtual DbSet<VerifyCode> VerifyCode { get; set; }

        public virtual DbSet<ContentBase> ContentBases { get; set; }

        public virtual DbSet<Content2> Content2s { get; set; }

        public virtual DbSet<Content> Contents { get; set; }


        public virtual DbSet<DataLog> DataLogs { get; set; }
        
        public virtual DbSet<Taxonomy> Taxonomys { get; set; }
        public virtual DbSet<TaxonomysItem> TaxonomysItem { get; set; }
        public virtual DbSet<TaxonomysItemBind> TaxonomysItemBind { get; set; }

        public virtual DbSet<IPInfo> IPInfo { get; set; }
        public virtual DbSet<AccessGeneral> AccessGeneral { get; set; }
        public virtual DbSet<AccessData> AccessData { get; set; }

        public virtual DbSet<PeriodicBackgroundJobLog> PeriodicBackgroundJobLogs { get; set; }

        #region OA

        public virtual DbSet<WorkFlow> WorkFlow { get; set; }

        public virtual DbSet<WorkFlowCategeory> WorkFlowCategeory { get; set; }

        public virtual DbSet<WorkFlowForm> WorkFlowForm { get; set; }

        public virtual DbSet<WorkFlowLogs> WorkFlowLogs { get; set; }

        public virtual DbSet<WorkFlowNode> WorkFlowNode { get; set; }

        public virtual DbSet<WorkFlowPaper> WorkFlowPaper { get; set; }

        public virtual DbSet<WorkFlowPaperArchive> WorkFlowPaperArchive { get; set; }

        public virtual DbSet<WorkFlowPaperData> WorkFlowPaperData { get; set; }

        public virtual DbSet<WorkFlowPaperListCtrl> WorkFlowPaperListCtrl { get; set; }

        public virtual DbSet<WorkFlowPaperListCtrlData> WorkFlowPaperListCtrlData { get; set; }

        public virtual DbSet<WorkFlowProcess> WorkFlowProcess { get; set; }

        public virtual DbSet<WorkFlowRelationship> WorkFlowRelationship { get; set; }

        public virtual DbSet<WorkFlowProcessMsg> WorkFlowProcessMsg { get; set; }

        public virtual DbSet<WorkFlowRunTime> WorkFlowRunTime { get; set; }

        public virtual DbSet<CommonShortMsg> CommonShortMsg { get; set; }

        #endregion

        #region Base

        public virtual DbSet<VersionInfo> VersionInfos { get; set; }

        public virtual DbSet<BackupBody> BackupBodys { get; set; }
        public virtual DbSet<BackupField> BackupFields { get; set; }

        public virtual DbSet<ContentBody> ContentBodys { get; set; }
        public virtual DbSet<ContentField> ContentFields { get; set; }

        public virtual DbSet<CacheBackUp> CacheBackUp { get; set; }

        public virtual DbSet<ShortIdTb> ShortIds { get; set; }

        public virtual DbSet<RolePermission> RolePermissionsNew { get; set; }
        public virtual DbSet<UserPermission> UserPermissionsNew { get; set; }
        public virtual DbSet<MtApplicationLanguage> MtLanguages { get; set; }
        public virtual DbSet<MtOrganizationUnit> MtOrganizationUnits { get; set; }

        public virtual DbSet<PersistedGrantEntity> PersistedGrants { get; set; }

        //-----

        public virtual DbSet<Friendship> Friendships { get; set; }
        public virtual DbSet<ChatMessage> ChatMessages { get; set; }
        public virtual DbSet<CustomConfiguration> CustomConfigurations { get; set; }
        public virtual DbSet<BinaryObject> BinaryObjects { get; set; }
        public virtual DbSet<FileObject> FileObjects { get; set; }

        public virtual DbSet<Menu> Menus { get; set; }
        public virtual DbSet<BackEndModule> BackEndModules { get; set; }

        public virtual DbSet<FrontEndPage> FrontEndPages { get; set; }

        public virtual DbSet<Bundling> Bundlings { get; set; }

        public virtual DbSet<PageView> PageViews { get; set; }

        public virtual DbSet<RouteSetting> RouteSettings { get; set; }

        public virtual DbSet<ContentMenu> ContentMenus { get; set; }

        public virtual DbSet<MenuConfig> MenuConfigs { get; set; }

        public virtual DbSet<ContentStorage> ContentStorages { get; set; }

        public virtual DbSet<Seo> Seos { get; set; }

        public virtual DbSet<StaticPage> StaticPages { get; set; }
        // 频道页
        public virtual DbSet<ChannelObject> ChannelObjects { get; set; }

        public virtual DbSet<UserDelegation> UserDelegations { get; set; }


        public virtual DbSet<Post> Post { get; set; }
        public virtual DbSet<PostOrganization> PostOrganization { get; set; }
        public virtual DbSet<UserPost> UserPost { get; set; }

        public virtual DbSet<UserExtension> UserExtension { get; set; }

        public virtual DbSet<MtUserNotificationInfo> MtUserNotifications { get; set; }

        public virtual DbSet<Directories> Directories { get; set; }
        public virtual DbSet<FileLibrary> FileLibrary { get; set; }

        public virtual DbSet<TemporaryFile> TemporaryFile { get; set; }
        public virtual DbSet<FileObjectEx> FileObjectEx { get; set; }
        #endregion

        /* NOTE: 
         *   Setting "Default" to base class helps us when working migration commands on Package Manager Console.
         *   But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
         *   pass connection string name to base classes. ABP works either way.
         */
        public MtSiteDbContext(DbContextOptions<MtSiteDbContext> options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            AuditLog.MaxParametersLength = 1048576; //1024*1024
            modelBuilder.Entity<AuditLog>()
                .Property(e => e.ReturnValue)
                .HasMaxLength(AuditLog.MaxReturnValueLength);

            base.OnModelCreating(modelBuilder);

            #region Discriminator

            modelBuilder.Entity<FeatureSetting>()
                .HasDiscriminator<string>("Discriminator")
                .HasValue<FeatureSetting>("FeatureSetting")
                .HasValue<EditionFeatureSetting>("EditionFeatureSetting")
                .HasValue<TenantFeatureSetting>("TenantFeatureSetting");

            modelBuilder.Entity<FeatureSetting>()
                .Property("Discriminator")
                .IsRequired()
                .HasMaxLength(50);

            modelBuilder.Entity<PermissionSetting>()
                 .HasDiscriminator<string>("Discriminator")
                 .HasValue<PermissionSetting>("PermissionSetting")
                 .HasValue<RolePermission>("RolePermission")
                 .HasValue<UserPermission>("UserPermission")
                 .HasValue<RolePermissionSetting>("RolePermissionSetting")
                 .HasValue<UserPermissionSetting>("UserPermissionSetting");

            modelBuilder.Entity<PermissionSetting>()
                .Property("Discriminator")
                .IsRequired()
                .HasMaxLength(50);

            modelBuilder.Entity<UserNotificationInfo>()
                .HasDiscriminator<string>("Discriminator")
                .HasValue<UserNotificationInfo>("UserNotificationInfo")
                .HasValue<MtUserNotificationInfo>("MtUserNotificationInfo");

            modelBuilder.Entity<UserNotificationInfo>()
                .Property("Discriminator")
                .IsRequired()
                .HasMaxLength(50);

            modelBuilder.Entity<OrganizationUnit>()
                .HasDiscriminator<string>("Discriminator")
                .HasValue<OrganizationUnit>("OrganizationUnit")
                .HasValue<MtOrganizationUnit>("MtOrganizationUnit");

            modelBuilder.Entity<OrganizationUnit>()
                .Property("Discriminator")
                .IsRequired()
                .HasMaxLength(50);

            modelBuilder.Entity<ApplicationLanguage>()
                .HasDiscriminator<string>("Discriminator")
                .HasValue<ApplicationLanguage>("ApplicationLanguage")
                .HasValue<MtApplicationLanguage>("MtApplicationLanguage");

            modelBuilder.Entity<ApplicationLanguage>()
                .Property("Discriminator")
                .IsRequired()
                .HasMaxLength(50);

            modelBuilder.Entity<ContentBase>()
                .HasDiscriminator<string>("Discriminator")
                .HasValue<ContentBase>("ContentBase")
                .HasValue<Content>("Content")
                .HasValue<Content2>("Content2");

            modelBuilder.Entity<ContentBase>()
                .Property("Discriminator")
                .IsRequired()
                .HasMaxLength(50);
            #endregion


            #region ChannelObject

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Title)
                .HasMaxLength(ChannelObject.MaxTitleLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Description)
                .HasMaxLength(ChannelObject.MaxDescriptionLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Text)
                .HasMaxLength(ChannelObject.MaxTextLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.LinkUrl)
                .HasMaxLength(ChannelObject.MaxLinkUrlLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Str1)
                .HasMaxLength(ChannelObject.MaxStrLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Str2)
                .HasMaxLength(ChannelObject.MaxStrLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Str3)
                .HasMaxLength(ChannelObject.MaxStrLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Str4)
                .HasMaxLength(ChannelObject.MaxStrLength);

            modelBuilder.Entity<ChannelObject>()
                .Property(e => e.Str5)
                .HasMaxLength(ChannelObject.MaxStrLength);

            #endregion

            //Abp.ZeroCore.IdentityServer4.EntityFrameworkCore.dll
            modelBuilder.ConfigurePersistedGrantEntity();

            modelBuilder.ChangeSysTablePrefix("Mt");
            modelBuilder.ChangeContentTablePrefix("App");
            modelBuilder.AddIndexForMtSiteDbContext();
        }
    }
}
